﻿namespace Deppton.Mobile
{
    using System;
    using Deppton.Mobile.Views;

    public class GpsController : IDisposable
    {
        private bool isDisposed;
        private Gps.Gps gps = new Gps.Gps();
        private EventHandler FormRequiresUpdate;
        private Gps.GpsPosition lastPosition;

        public GpsController()
        {
            this.GpsForm = new AcquiringGpsPositionForm();
            this.GpsForm.ContinueCheckChanged += new EventHandler(GpsFormContinueCheckChanged);
            this.gps.LocationChanged += new Deppton.Mobile.Gps.LocationChangedEventHandler(GpsLocationChanged);
            this.FormRequiresUpdate = new EventHandler(this.UpdateInformation);
        }

        public Gps.GpsPosition CapturePosition()
        {
            try
            {
                if (this.GpsForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    return this.lastPosition;
                }
                else
                {
                    return null;
                }
            }
            finally
            {
                this.gps.Close();
            }
        }

        public Func<bool, Gps.GpsPosition> GpsPositionValidation
        {
            get;
            set;
        }

        public Gps.GpsPosition LastPosition
        {
            get
            {
                return this.lastPosition;
            }
        }

        void GpsLocationChanged(object sender, Deppton.Mobile.Gps.LocationChangedEventArgs args)
        {
            if (args.Position.LatitudeValid && args.Position.LongitudeValid)
            {
                this.lastPosition = args.Position;
                this.GpsForm.Invoke(this.FormRequiresUpdate);
            }
        }

        void GpsFormContinueCheckChanged(object sender, EventArgs e)
        {
            if (this.GpsForm.CapturePositionChecked)
            {
                gps.Open();
                this.GpsForm.AcquiringLegend = "GPS encendido.";
            }
            else
            {
                gps.Close();
                this.GpsForm.AcquiringLegend = "GPS apagado.";
            }
        }

        private void UpdateInformation(object sender, EventArgs args)
        {
            if (this.lastPosition != null)
            {
                this.GpsForm.ResultsLegend = string.Format("Última posición:\nLat: {0}\nLon: {1}", this.lastPosition.LatitudeInDegreesMinutesSeconds.ToString(), this.lastPosition.LongitudeInDegreesMinutesSeconds.ToString());
            }

            this.GpsForm.AllowContinue = this.lastPosition != null;
        }

        public AcquiringGpsPositionForm GpsForm
        {
            get;
            set;
        }

        ~GpsController()
        {
            this.Dispose(false);
        }

        public void Dispose()
        {
            this.Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!this.isDisposed)
            {
                if (disposing)
                {
                    if (this.GpsForm != null)
                    {
                        this.GpsForm.Dispose();
                    }
                    if (this.gps != null)
                    {
                        this.gps.Close();
                    }
                }

                this.isDisposed = true;
            }
        }
    }
}
